extends Node
class_name ModParseUtil


static func try_parse_resource2(resource,top_json):
	if resource == null: return {}
	
	if resource.resource_path.ends_with("common_tileset.tres"):
		pass
	var is_local = resource_is_local(resource)
	var resource_json = {}
	resource_json["local"] = is_local
	# 如果是本地资源
	if is_local:
		var temp:Dictionary = top_json.get("resource",{}).get(resource.resource_path,{})
		# 是空的就需要解析
		if temp.empty():
			# 这里注意一下，检测是否可以直接进行load
			
			var temp_texture_json = resource_parse(resource)
			# 再把这个资源注册到最顶层
			top_json["resource"][resource.resource_path] = temp_texture_json
			pass
		# 不是空的说明是需要直接使用的
		resource_json["key"] = resource.resource_path
		pass
	else:
		var temp_texture_json = resource_parse(resource)
		resource_json["info"] = temp_texture_json
	return resource_json
# 尝试解析资源
# 只有tilemap .sprite ,texturerect有这个资源
static func try_parse_resource(item,info,top_json):
	info["texture"] = {}
	var item_res = null
	# 目前只解析这两个资源
	if item is Sprite or item is TextureRect:
		if item.texture != null: item_res = item.texture
		pass
	if item is TileMap:
		item_res = item.tile_set
	# 如果资源不为空
	if item_res != null:
		var temp_json = try_parse_resource2(item_res,top_json)
		info["texture"].merge(temp_json,true)
	if info["texture"].empty():
		info.erase("texture")
	pass
# 下面的只解析共有数据，注意不会包括脚本数据再里面，脚本数据需要按需提取
# 将texture 解析成json
static func parse_texture_rect(item:TextureRect)->Dictionary:
	var node_item = {}
	node_item["type"] = "TextureRect"
	node_item["flip_h"] = item.flip_h
	node_item["flip_v"] = item.flip_v
	node_item["modulate"] = [item.modulate.r,item.modulate.g,item.modulate.b,item.modulate.a]
	node_item["type"] = "TextureRect"
	node_item["expand"] = item.expand
	node_item["stretch_mode"] = item.stretch_mode
	node_item["position"] =  [item.rect_position.x,item.rect_position.y]
	node_item["scale"] = [item.rect_scale.x,item.rect_scale.y]
	node_item["size"] = [item.rect_size.x,item.rect_size.y]
	node_item["visible"] = item.visible
	node_item["name"] = item.name
	
	return node_item
static func parse_color_rect(item:ColorRect)->Dictionary:
	var node_item = {}
	node_item["type"] = "ColorRect"
	node_item["modulate"] = [item.modulate.r,item.modulate.g,item.modulate.b,item.modulate.a]
	node_item["color"] = [item.color.r,item.color.g,item.color.b,item.color.a]
	node_item["position"] =  [item.rect_position.x,item.rect_position.y]
	node_item["scale"] = [item.rect_scale.x,item.rect_scale.y]
	node_item["size"] = [item.rect_size.x,item.rect_size.y]
	node_item["visible"] = item.visible
	node_item["name"] = item.name
	return node_item
# 将sprite 解析成json
static func parse_sprite(item:Sprite) ->Dictionary:
	var node_item = {}
	node_item["type"] = "Sprite"
	node_item["flip_h"] = item.flip_h
	node_item["flip_v"] = item.flip_v
	node_item["modulate"] = [item.modulate.r,item.modulate.g,item.modulate.b,item.modulate.a]
	node_item["position"] = [item.position.x,item.position.y]
	node_item["scale"] = [item.scale.x,item.scale.y]
	node_item["z_index"] = item.z_index
	node_item["centered"] = item.centered
	node_item["offset"] = [item.offset.x,item.offset.y]
	node_item["visible"] = item.visible
	node_item["name"] = item.name
	node_item["animtaion_hframes"] = item.hframes
	node_item["animtaion_vframes"] = item.vframes
	node_item["frame"] = item.frame
	node_item["frame_coords"] = [item.frame_coords.x,item.frame_coords.y]
	
	return node_item
# 将tilemap 解析成json
static func parse_tilemap(node:TileMap)->Dictionary:
	var node_item = {}
	node_item["type"] = "TileMap"
	node_item["mode"] = node.mode
	node_item["cell_size"] = [node.cell_size.x,node.cell_size.y]
	node_item["collision_use_parent"] = node.collision_use_parent
	node_item["position"] = [node.position.x,node.position.y]
	node_item["collision_layer"] = node.collision_layer
	node_item["cokkision_mask"] = node.collision_mask
	node_item["visible"] = node.visible
	node_item["show_collision"] = node.show_collision
	node_item["name"] = node.name
	node_item["z_index"] = node.z_index
	# key是id：value是数组，全是二维的
	node_item["cells"] = {}
	var cells_pos = node.get_used_cells()
	for pos in cells_pos:
		var cell_id = node.get_cell(pos.x,pos.y)
		
		var pos_array = node_item["cells"].get(str(cell_id),[])
		pos_array.append([pos.x,pos.y])
		node_item["cells"][str(cell_id)] = pos_array
	# tilemap 不允许有碰撞相关的，不设置，由上层的area2d来进行控制
	return node_item
# 将area2d解析成json
static func parse_area2d(node:Area2D)->Dictionary:
	var node_item = {}
	node_item["type"] = "Area2D"
	# 主要涉及的有碰撞区域，位置
	node_item["monitoring"] = node.monitoring
	node_item["monitorable"] = node.monitorable
	node_item["position"] = [node.position.x,node.position.y]
	node_item["z_index"] = node.z_index
	# 还有碰撞的区域设置
	node_item["collision_layer"] = node.collision_layer
	node_item["collision_mask"] = node.collision_mask
	node_item["visible"] = node.visible
	node_item["name"] = node.name
	return node_item
	pass
# 将light2d解析为json
static func parse_light2d(node:Light2D)->Dictionary:
	var node_item = {}
	node_item["type"] = "Light2D"
	# enabled必须要开[这里预留]
	node_item["enabled"] = node.enabled
	node_item["texture_scale"] = node.texture_scale
	node_item["color"] = [node.color.r,node.color.g,node.color.b,node.color.a]
	node_item["energy"] = node.energy
	node_item["mode"] = node.mode
	# 暂时不支持range 和shadow,以后再说
	node_item["name"] = node.name
	node_item["position"] = [node.position.x,node.position.y]
	node_item["scale"] = [node.scale.x,node.scale.y]
	# visible的属性也不管
	return node_item

# 将polygon2d解析成json
static func parse_collision_polygon2d(node:CollisionPolygon2D)->Dictionary:
	var node_item = {}
	# build_mode 为默认
	node_item["type"] = "CollisionPolygon2D"
	node_item["position"] = [node.position.x,node.position.y]
	node_item["z_index"] = node.z_index
	node_item["visible"] = node.visible
	node_item["polygon"] = []
	node_item["name"] = node.name
	for v2 in node.polygon:
		node_item["polygon"].append([v2.x,v2.y])
	return node_item
	pass



# 下面是对资源的解析
# 解析出这个资源的属性
static func resource_parse(resource:Resource):
	var info = {}
	# 切片资源
	if resource is AtlasTexture:
		info.merge(resource_parse_atlas(resource),true)
	# 动画资源[使用了切片的资源]
	if resource is AnimatedTexture:
		info.merge(resource_parse_animated_texture(resource),true)
	# 外部流文件
	if resource is StreamTexture:
		info.merge(resource_parse_stream_texture(resource),true)
	# tileset文件
	if resource is TileSet:
		info.merge(resource_parse_tileset(resource),true)
	return info
# 解析流资源
static func resource_parse_stream_texture(resource:StreamTexture):
	var info = {}
	#表示直接load进去的
	info["type"] = "StreamTexture"
	# 流文件只有这个路径
	info["path"] = resource.resource_path
	
	info["path"] = info["path"].substr(info["path"].find("assets"))
	return info
# 解析atlas资源
static func resource_parse_atlas(resource:AtlasTexture):
	var info = {}
	info["type"] = "AtlasTexture"
	info["path"] = resource.atlas.resource_path
	info["path"] = info["path"].substr(info["path"].find("assets"))
	info["region"] = [resource.region.position.x,resource.region.position.y,resource.region.size.x,resource.region.size.y]
	info["margin"] = [resource.margin.position.x,resource.margin.position.y,resource.margin.size.x,resource.margin.size.y]
	return info
# 解析animtaed_texture
static func resource_parse_animated_texture(resource:AnimatedTexture):
	var info = {}
	info["type"] = "AnimatedTexture"
	info["frames"] = []
	info["fps"] = resource.fps
	for i in resource.frames:
		var temp = {}
		info["frames"].append(temp)
		var texture = resource.get_frame_texture(i)
		# 这个texture一定是一个 StreamTexture .因为AtlasTexture会无效
		var delay = resource.get_frame_delay(i)
		if texture != null:
			temp["path"] = texture.resource_path
			temp["path"] = temp["path"].substr(temp["path"].find("assets"))
		else:
			temp["path"] = ""
		temp["delay"] = delay
	return info
static func resource_parse_tileset(resource:TileSet):
	var info = {}
	var tile = {}
	info["type"] = "TileSet"
	info["tile"] = tile
	var ids = resource.get_tiles_ids()
	# 可以允许这两个参数
	if resource.get_script() != null:
		info["separation"] = [resource.separation.x,resource.separation.y]
		info["option_offset"] = [resource.option_offset.x,resource.option_offset.y]
	for id in ids:
		var temp = {}
		tile[str(id)] = temp
		# 这个一定是一个 stream
		var texture = resource.tile_get_texture(id)
		# 流文件
		var texture_info = resource_parse_stream_texture(texture)
		
		var tex_offset = resource.tile_get_texture_offset(id)
		var tex_modulate = resource.tile_get_modulate(id)
		var tex_region = resource.tile_get_region(id)
		var tile_mod = resource.tile_get_tile_mode(id)
		
		temp["texture_info"] = texture_info
		temp["texture_offset"] = [tex_offset.x,tex_offset.y]
		temp["texture_modulate"] = [tex_modulate.r,tex_modulate.g,tex_modulate.b,tex_modulate.a]
		temp["texture_region"] = [tex_region.position.x,tex_region.position.y,tex_region.size.x,tex_region.size.y]
		temp["tile_mod"] = tile_mod
		
		# 永远都是第一个shape
		var shapes = resource.tile_get_shapes(id)
		var shapes_json_array = []
		temp["shapes"] = shapes_json_array
		
#		var shape = resource.tile_get_shape(id,0)
		for shape in shapes:
			var shape_temp = {}
			if shape != null:
				if shape["shape"] is ConvexPolygonShape2D:
					shape_temp["ConvexPolygonShape2D_shape"] = []
					var c_shape:ConvexPolygonShape2D = shape["shape"]
					for p in c_shape.points:
						shape_temp["ConvexPolygonShape2D_shape"].append([p.x,p.y])
				elif shape["shape"] is RectangleShape2D:
					var c_shape:RectangleShape2D = shape["shape"]
					shape_temp["RectangleShape2D_shape"] = [c_shape.extents.x,c_shape.extents.y]
				var tf2d:Transform2D = shape["shape_transform"]
				shape_temp["shape_transform"] = [
					[tf2d.x.x,tf2d.x.y],
					[tf2d.y.x,tf2d.y.y],
					[tf2d.origin.x,tf2d.origin.y],
				]
				
			if !shape_temp.empty():
				shapes_json_array.append(shape_temp)
		pass
	return info




# ==================================================
# author: lxl
# description：资源是否再本地被保存为文件
# true 说明这个资源被保存为了tres或者其他格式的
# false 说明这个资源是临时资源文件
# ==================================================
static func resource_is_local(res:Resource)->bool:
	return !res.resource_path.find_last("::") != -1 and !res.resource_path.empty()
# ==================================================
# author: lxl
# description：这个用于解析collision_layer 和mask的
# ==================================================
static func num_to_bit(num)->Array:
	var bit = []
	for i in 32:
		if (num &( 1 << i)):
			bit.append(1)
		else:
			bit.append(0)
	return bit
